﻿
Imports osi.root.delegates
Imports osi.root.utils

Public Module _async_sync
    'for test only
    Private Delegate Function begin_d(Of T)(ByVal c As T) As Boolean

    Private Function async_sync(ByVal ec As event_comb,
                                ByVal begin As begin_d(Of event_comb),
                                ByVal d As _do(Of _do(Of Boolean), Boolean)) As Boolean
        assert(Not begin Is Nothing)
        assert(Not d Is Nothing)
        If ec Is Nothing Then
            Return False
        Else
            assert(ec.not_started())
            If begin(ec) Then
                Return d(Function() ec.end()) AndAlso ec.end_result()
            Else
                Return False
            End If
        End If
    End Function

    Public Function async_sync(ByVal ec As event_comb) As Boolean
        Return async_sync(ec,
                          AddressOf begin,
                          Function(ByRef x As _do(Of Boolean)) As Boolean
                              timeslice_sleep_wait_until(x)
                              Return True
                          End Function)
    End Function

    Public Function async_sync(ByVal ec As event_comb, ByVal timeout_ms As Int64) As Boolean
        Return async_sync(ec,
                          Function(e) begin(e, timeout_ms),
                          Function(ByRef x) timeslice_sleep_wait_until(x, timeout_ms))
    End Function

    Public Sub assert_async_sync(ByVal ec As event_comb)
        assert(async_sync(ec))
    End Sub

    Public Sub assert_async_sync(ByVal ec As event_comb, ByVal timeout_ms As Int64)
        assert(async_sync(ec, timeout_ms))
    End Sub

    Private Function async_sync(ByVal cb As callback_action,
                                ByVal begin As begin_d(Of callback_action),
                                ByVal d As _do(Of _do(Of Boolean), Boolean)) As Boolean
        assert(Not begin Is Nothing)
        assert(Not d Is Nothing)
        If cb Is Nothing Then
            Return False
        Else
            assert(cb.begining())
            If begin(cb) Then
                Return d(Function() cb.finished()) AndAlso cb.success_finished()
            Else
                Return False
            End If
        End If
    End Function

    Public Function async_sync(ByVal cb As callback_action) As Boolean
        Return async_sync(cb,
                          AddressOf begin,
                          Function(ByRef x As _do(Of Boolean)) As Boolean
                              timeslice_sleep_wait_until(x)
                              Return True
                          End Function)
    End Function

    Public Function async_sync(ByVal cb As callback_action, ByVal timeout_ms As Int64) As Boolean
        Return async_sync(cb,
                          Function(c) begin(c, timeout_ms),
                          Function(ByRef x) timeslice_sleep_wait_until(x, timeout_ms))
    End Function

    Public Sub assert_async_sync(ByVal cb As callback_action)
        assert(async_sync(cb))
    End Sub

    Public Sub assert_async_sync(ByVal cb As callback_action, ByVal timeout_ms As Int64)
        assert(async_sync(cb, timeout_ms))
    End Sub
End Module
